﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using EpiNEXT.Services;
using EpiNEXT.Services.Data;
using EpiNEXT.Services.Fields;
using EpiNEXT.Data;

namespace EpiNEXT.Applications
{
    public class ProjectFactory
    {
        public Project CreateProject(string fileName)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();

            XmlSerializer serializer = new XmlSerializer(typeof(Project));

            using (StreamReader streamReader = new StreamReader(fileName))
            {
                Project project = (Project)serializer.Deserialize(streamReader);
                project.ProjectFilePath = fileName;

                // TODO: Re-enable this synchronization somehow, maybe by moving the methods from Services into this method?
                //project.InitalizeRecordCollectionSynchronization();
                
                DataDriverFactory dataDriverFactory = new DataDriverFactory();
                IDbDriver database = dataDriverFactory.CreateDataDriver(project.DataDriverString, project.DataLocation);
                project.Database = database;

                foreach (CodeList codeList in project.CodeLists)
                {
                    //if (codeList.Concatenate)
                    //{
                        foreach (CodeListValue listValue in codeList.CodeListValues)
                        {
                            //listValue.Display = listValue.Store + codeList.Separator + listValue.Display;
                            listValue.Owner = codeList;
                        }
                    //}
                }

                foreach (Form form in project.Forms)
                {
                    form.Owner = project;
                    foreach (Page page in form.Pages)
                    {
                        page.Owner = form;
                    }

                    FieldCollectionFactory fieldCollectionFactory = new FieldCollectionFactory(project, form);
                    form.Fields = fieldCollectionFactory.GetFieldCollection();

                    if (form is Form)
                    {
                        foreach (Page page in (form as Form).Pages)
                        {
                            page.UpdateFields();
                        }
                    }

                    // get parent form for related form relationships
                    foreach (Form iForm in project.Forms)
                    {
                        if (iForm != form && form.ParentFormId.Equals(iForm.FormId))
                        {
                            form.ParentForm = iForm;
                        }
                    }

                    database.PopulateRecordCollection(form);
                }

                foreach (DataGridTable table in project.DataGridTables)
                {
                    table.Owner = project;

                    FieldCollectionFactory fieldCollectionFactory = new FieldCollectionFactory(project, table);
                    table.Fields = fieldCollectionFactory.GetFieldCollection();
                    project.Database = database;

                    // get parent form for related form relationships
                    foreach (Form iForm in project.Forms)
                    {
                        if (table.ParentFormId.Equals(iForm.FormId))
                        {
                            table.ParentForm = iForm;
                        }
                    }

                    database.PopulateRecordCollection(table);
                }

                //switch (project.DataDriverUpdateMode)
                //{
                //    case DataDriverUpdateMode.None:
                //        // do nothing
                //        break;
                //    case DataDriverUpdateMode.Timer:
                //        // set up a timer to check the database
                //        project.InitializeTimer(5000);
                //        break;
                //    case DataDriverUpdateMode.ServiceBroker:
                //        // set up a service broker to check the database
                //        throw new NotImplementedException("Service broker is not implemented at this time.");
                //        break;
                //}

                stopwatch.Stop();
                System.Diagnostics.Debug.Print(stopwatch.Elapsed.TotalMilliseconds.ToString() + " ms to load.");

                return project;
            }
        }
    }
}
